package net.yunxinyong.sign.utils;


import com.alibaba.fastjson.JSONObject;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.processing.OperationManager;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.FileInfo;
import com.qiniu.storage.model.FileListing;
import com.qiniu.util.Auth;
import com.qiniu.util.Base64;
import com.qiniu.util.StringMap;
import com.qiniu.util.UrlSafeBase64;

import lombok.extern.log4j.Log4j2;
import net.yunxinyong.sign.aop.CECException;
import net.yunxinyong.sign.controller.CecBaseController;
import net.yunxinyong.sign.vo.QiniuVo;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Date;
import java.util.List;

@Log4j2
public class QiniuUtils {

    // 设置需要操作的账号的AK和SK
    private static final String ACCESS_KEY = "hR8mA_bT9z4n6zoy9Y_mEv1PtLbqdQMUHcDcTtLj";
    private static final String SECRET_KEY = "v9M1GhUg9IzMMZQeP4z1vNdZ0PAVsnqq04E-pryZ";
    // 要上传的空间
    private static final String BUCKET_EXAMINE = "examine";       //存储空间名称
    private static final String DOMAIN_EXAMINE= "examine.yicuojin.com";       //外链域名

    // 要上传的空间
    private static final String BUCKET_REGISTER = "register";//存储空间名称
    private static final String DOMAIN_REGISTER = "register.yicuojin.com";//外链域名

    // 压缩要上传的空间
    private static final String BUCKET_MKZIP = "mkzip";//存储空间名称
    private static final String DOMAIN_MKZIP = "mkzip.yicuojin.com";//外链域名

    // 密钥
    private static final Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);

    /**
     * 七牛回调URL
     */
    public static final String NOTIFY_URL = "*******";

    private static final String style = "自定义的图片样式";


    /**
     *
     * @param suffix 文件名称
     * @param name 企业名称
     * @param type 1 为添加examine  2为register
     * @return
     * @throws Exception
     */
    public static QiniuVo QiniuUpToken(String suffix, String name, Integer type) throws Exception{
        QiniuVo qiniuVo = new QiniuVo();
        try {
            //验证七牛云身份是否通过
            //Auth auth = Auth.create(accessKey, secretKey);
            //生成凭证
            if (type == 1){
                String upToken = auth.uploadToken(BUCKET_EXAMINE);
                qiniuVo.setToken(upToken);
                //存入外链默认域名，用于拼接完整的资源外链路径

                qiniuVo.setDomain(DOMAIN_EXAMINE);
            }else {
                String upToken = auth.uploadToken(BUCKET_REGISTER);
                qiniuVo.setToken(upToken);
                //存入外链默认域名，用于拼接完整的资源外链路径

                qiniuVo.setDomain(DOMAIN_REGISTER);
            }

            // 是否可以上传的图片格式
            boolean flag = false;
            String[] imgTypes = new String[]{"jpg","jpeg","bmp","gif","png","pdf"};
            for(String fileSuffix : imgTypes) {
                if(suffix.substring(suffix.lastIndexOf(".") + 1).equalsIgnoreCase(fileSuffix)) {
                    flag = true;
                    break;
                }
            }
            if(!flag) {
                throw new CECException(501,"图片：" + suffix + " 上传格式不对！");
            }
            Date date = new Date();
            //生成实际路径名
            String randomFileName = name+date.getTime() + suffix;
            qiniuVo.setImgUrl(randomFileName);
            System.out.println(qiniuVo.toString());
            return qiniuVo;

        } catch (Exception e) {
            throw new CECException(501,"获取凭证失败，"+e.getMessage());
        }
    }




    public static String getUpToken() {
        System.out.println("upToken:"+auth.uploadToken(BUCKET_REGISTER, null, 3600, new StringMap().put("insertOnly", 1)));
        return auth.uploadToken(BUCKET_REGISTER, null, 3600, new StringMap().put("insertOnly", 1));
    }



    // 普通上传
    public static String upload(String filePath, String fileName) throws IOException {
        // 创建上传对象
        UploadManager uploadManager = new UploadManager();
        try {
            // 调用put方法上传
            String token = auth.uploadToken(BUCKET_REGISTER);
            if(StringUtils.isEmpty(token)) {
                System.out.println("未获取到token，请重试！");
                return null;
            }
            Response res = uploadManager.put(filePath, fileName, token);
            // 打印返回的信息
            System.out.println(res.bodyString());
            if (res.isOK()) {
                Ret ret = res.jsonToObject(Ret.class);
                //如果不需要对图片进行样式处理，则使用以下方式即可
                return DOMAIN_REGISTER + ret.key;
                //return DOMAIN + ret.key + "?" + style;
            }
        } catch (QiniuException e) {
            Response r = e.response;
            // 请求失败时打印的异常的信息
            System.out.println(r.toString());
            try {
                // 响应的文本信息
                System.out.println(r.bodyString());
            } catch (QiniuException e1) {
                // ignore
            }
        }
        return null;
    }

    //base64方式上传
    public static String put64image(byte[] base64, String key) throws Exception{
        String file64 = Base64.encodeToString(base64, 0);
        Integer len = base64.length;

        String url = "http://upload.qiniu.com/putb64/" + len + "/key/"+ UrlSafeBase64.encodeToString(key);

        RequestBody rb = RequestBody.create(null, file64);
        Request request = new Request.Builder()
                .url(url)
                .addHeader("Content-Type", "application/octet-stream")
                .addHeader("Authorization", "UpToken " + getUpToken())
                .post(rb).build();

        OkHttpClient client = new OkHttpClient();
        okhttp3.Response response = client.newCall(request).execute();
        System.out.println(response);
        //如果不需要添加图片样式，使用以下方式
        return DOMAIN_REGISTER + key;
        //return DOMAIN + key + "?" + style;
    }



    public static String getUrl(String key){
        if(!StringUtils.isEmpty(key)){
            return auth.privateDownloadUrl("http://"+key);
        }
        return null;
    }

    class Ret {
        public long fsize;
        public String key;
        public String hash;
        public int width;
        public int height;
    }



    /**
     * @Description: 大量文件压缩
     * return 压缩文件下载地址
     * type = 1 为添加企业数据批量下载 =2 登记数据批量下载
     */
    public static String mkzip(List<String> urlList, Integer type,String name) throws IOException {


        String key ="index.txt";
        //设置压缩操作参数
        //新建一个OperationManager对象
        OperationManager operater = new OperationManager(auth);
        //设置要转码的空间和key，并且这个key在你空间中存在
        String bucket = BUCKET_REGISTER;
        if (type == 1){
            bucket = BUCKET_EXAMINE;
        }else if (type == 2){
            bucket = BUCKET_REGISTER;
        }



        String fops = "mkzip/2";
        //for循环参数
        for (String s:urlList){
            if (getUrl(s) != null){
                fops += "/url/"+UrlSafeBase64.encodeToString(getUrl(s));
            }
        }
        //设置转码的队列
        //String pipeline = "";
        //可以对转码后的文件进行使用saveas参数自定义命名，当然也可以不指定文件会默认命名并保存在当前空间。
        String urlbase64 = UrlSafeBase64.encodeToString("mkzip:"+name+".zip");
        String pfops = fops + "|saveas/"+urlbase64;
        //String pfops = fops;
        //设置pipeline参数
        //StringMap params = new StringMap().putWhen("force", 1, true).putNotEmpty("pipeline", pipeline);
        try {
            String persistid = operater.pfop(bucket, key, pfops);
            //JSONObject jsonObject = JSONObject.parseObject(persistid);
            //打印返回的persistid
            System.out.println("persistid:"+persistid);

            String http = CECHTTPUtils.getHttp("http://api.qiniu.com/status/get/prefop?id=" + persistid, "utf-8");
            JSONObject jsonObject = JSONObject.parseObject(http);
            System.out.println("http:"+jsonObject.get("code"));
            //根据persistid判断操作是否成功
            if (!jsonObject.get("code").equals(3)){
                return getUrl(DOMAIN_MKZIP+"/"+name+".zip");
            }else {
                log.error(jsonObject);
                throw new CECException(501,"操作失败");
            }
        } catch (QiniuException e) {
            //捕获异常信息
            Response r = e.response;
            // 请求失败时简单状态信息
            System.out.println("请求失败时简单状态信息"+r.toString());
            try {
                // 响应的文本信息
                System.out.println("响应的文本信息"+r.bodyString());
            } catch (QiniuException e1) {
                //ignore
            }
            throw new CECException(501,"操作失败");
        }

    }
}








